﻿using System.Collections.Generic;
using System.Linq;
using Arena_Server.Infrastructure;
using Common_Library;
using Common_Library.Infrastructure;
using Common_Library.Parts_of_map;

namespace GamePlay_Preview.PlayersTools
{
    /// <summary>
    /// Class that translates the code of moves/states
    /// </summary>
    public static class Translator
    {
        /// <summary>
        /// Sortowanie indeksow z listy MoveHistory na podstawie liczny punktów, uzyskanych za każdy ruch
        /// </summary>
        /// <param name="sorted"></param>
        /// <param name="states"></param>
        public static void AddAndSortStates(ref Dictionary<int, double> sorted, List<PlayerState> states, bool add = false)
        {
            if (add)
            {
                var last = states.Last();
                sorted.Add(states.Count - 1, last.PlayerScore);
            }
            else
            {
                sorted.Clear();
                for (int i = 0; i < states.Count; i++)
                    sorted.Add(i, states[i].PlayerScore);
            }

            IOrderedEnumerable<KeyValuePair<int, double>> items = from pair in sorted
                                                                  orderby pair.Value descending
                                                                  select pair;
            sorted = items.ToDictionary(x => x.Key, x => x.Value);
        }


        /// <summary>
        /// Translates our moves defined in "state" object into an adequate PossibleAction to be applied in the game
        /// </summary>
        /// <param name="state">Information about the move and state. Here in this method we use only info about the move</param>
        /// <returns></returns>
        //public static PossibleAction TranslateMove(PlayerState state)
        //{
        //    Directions direction = (Directions)state.Move[0];
        //    MoveType moveType = (MoveType)state.Move[1];

        //    return new PossibleAction(moveType, direction);
        //}

        /// <summary>
        /// Adds the state of the robot and the consequences of the made move and adds the to "state"
        /// </summary>
        /// <param name="state">Previously defined object, containing only information about the move</param>
        /// <param name="game">Information about the current state of the game</param>
        /// <returns></returns>
        public static void AddState(ref PlayerState state, MoveConsequence lastConsequence, Position myPosition, Map currentMap, PossibleAction action = null)
        {
            //dodaj punktacje za ruch
            //state.PlayerScore = last.MyCurrentPay;

            var column = myPosition.X < 8 ? myPosition.X : 8;
            var row = myPosition.Y < 8 ? myPosition.Y : 8;
            if (action != null && action.Action == MoveType.MakeMove)
            {
                if (action.MoveDirection == Directions.Left)
                    column--;
                else if (action.MoveDirection == Directions.Right)
                    column++;
                else if (action.MoveDirection == Directions.Down)
                    row++;
                else if (action.MoveDirection == Directions.Up)
                    row--;
            }

            //pole, na ktorym wlasnie stoi robot
            state.State[0] = GetColor(currentMap.GlobalMap[row, column].Color);

            //pole po lewej
            if (currentMap.GlobalMap[row, column - 1] is Wall)
                state.State[1] = GetColor(currentMap.GlobalMap[row, column - 1].Color);

            //pole po prawej
            if (currentMap.GlobalMap[row, column + 1] is Wall)
                state.State[2] = GetColor(currentMap.GlobalMap[row, column + 1].Color);

            //pole powyzej
            if (currentMap.GlobalMap[row - 1, column] is Wall)
                state.State[3] = GetColor(currentMap.GlobalMap[row - 1, column].Color);

            //pole ponizej
            if (currentMap.GlobalMap[row + 1, column] is Wall)
                state.State[4] = GetColor(currentMap.GlobalMap[row + 1, column].Color);

            //konsekwencje ruchu
            state.ConsequenceOfMove = lastConsequence;


        }

        public static PlayerState GetTempState(ClientsGamePreview game, PossibleAction action = null)
        {
            var state = new PlayerState();

            var column = game.MyPosition.X < 8 ? game.MyPosition.X : 8;
            var row = game.MyPosition.Y < 8 ? game.MyPosition.Y : 8;
            if (action != null && action.Action == MoveType.MakeMove)
            {
                if (action.MoveDirection == Directions.Left)
                    column--;
                else if (action.MoveDirection == Directions.Right)
                    column++;
                else if (action.MoveDirection == Directions.Down)
                    row++;
                else if (action.MoveDirection == Directions.Up)
                    row--;
            }

            //pole, na ktorym wlasnie stoi robot
            state.State[0] = GetColor(game.CurrentMap.GlobalMap[row, column].Color);

            //pole po lewej
            if (game.CurrentMap.GlobalMap[row, column - 1] is Wall)
                state.State[1] = GetColor(game.CurrentMap.GlobalMap[row, column - 1].Color);

            //pole po prawej
            if (game.CurrentMap.GlobalMap[row, column + 1] is Wall)
                state.State[2] = GetColor(game.CurrentMap.GlobalMap[row, column + 1].Color);

            //pole powyzej
            if (game.CurrentMap.GlobalMap[row - 1, column] is Wall)
                state.State[3] = GetColor(game.CurrentMap.GlobalMap[row - 1, column].Color);

            //pole ponizej
            if (game.CurrentMap.GlobalMap[row + 1, column] is Wall)
                state.State[4] = GetColor(game.CurrentMap.GlobalMap[row + 1, column].Color);

            return state;
        }

        /// <summary>
        /// Przeksztalca kolor, podany jako string, na jego liczbowa reprezentacje
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        public static int GetColor(string color)
        {
            int _intColor = 0;
            switch (color)
            {
                case "Default":
                    _intColor = 1;
                    break;

                case "Red":
                    _intColor = 2;
                    break;

                case "Blue":
                    _intColor = 3;
                    break;

                case "Green":
                    _intColor = 4;
                    break;

                case "Yellow":
                    _intColor = 5;
                    break;

                case "Orange":
                    _intColor = 6;
                    break;

                case "Violet":
                    _intColor = 7;
                    break;

                case "Black":
                    _intColor = 8;
                    break;

                default:
                    _intColor = 9;
                    break;
            }
            return _intColor;
        }



        public static Position GetMyLocalPosition(Position myGlobalPosition)
        {
            var x = myGlobalPosition.X < 8 ? myGlobalPosition.X : 8;
            var y = myGlobalPosition.Y < 8 ? myGlobalPosition.Y : 8;
            return new Position(x, y);
        }

        public static Position GlobalToLocalPosition(Position myPosition, Position position)
        {
            var myLocalPosition = GetMyLocalPosition(myPosition);
            var x = myLocalPosition.X + (position.X - myPosition.X);
            var y = myLocalPosition.Y + (position.Y - myPosition.Y);
            return new Position(x, y);
        }

    }
}
